
#include "Worker.h"


//////////////////////////////
Worker*  _WORKER;
Worker g_Worker;
/////////////////////////////////

Counter g_SelectCounter;
Counter g_UpdateCounter;
Counter g_UpRoleIDCounter;

void PrintCnt(bool bforce);

///////////////////////////////
Worker::Worker()
{
    _WORKER = &g_Worker;
}

Worker::~Worker()
{
    SMART_LOCK_THIS();

    map<string, NameExist*, MapStringComp>::iterator it;

    for (it = m_playerNames.begin(); it != m_playerNames.end(); it++)
    {
        SAFE_DELETE( it->second );
    }

    for (it = m_FamilyNames.begin(); it != m_FamilyNames.end(); it++)
    {
        SAFE_DELETE( it->second );
    }
}


string getfix_name( map<string,  NameExist*,  MapStringComp > & names, string& name, int& fix)
{
    char tmp[ 128 ];

    string ret;
    while (1)
    {
        //ret = ret + itoa(fix, tmp, 10);
        sprintf(tmp, "%s(%d)", name.c_str(),  fix ++);

        if ( names.find( tmp ) == names.end())
        {
            break;
        }
    }
    return tmp;
}

bool   cp_int(int   s1,   int   s2)
{
    return   s1 < s2;
}

void Worker::DoMerge()
{
    printf("开始筛选重复角色名和工会名.\n");

    // 第一步，取出角色名和工会名
    /////////////////////////////////////////////////////////
    {
        CMsgTyped param;
        param.SetInt( 0 );
        _PROC->Call( _CONFIG->master.Proc_Manage,   Async_SelectPlayerName,  &param);

        g_SelectCounter.IncRef();
    }

    {
        CMsgTyped param;
        param.SetInt( 0 );
        _PROC->Call(_CONFIG->master.Proc_Family,   Async_SelectFamilyName,  &param);

        g_SelectCounter.IncRef();
    }

    for (size_t i=0;  i < _CONFIG->slaves.size();  i++)
    {
        // 第一步，取出角色名和工会名
        {
            CMsgTyped param;
            param.SetInt( i + 1 );
            _PROC->Call( _CONFIG->slaves[i].Proc_Manage,   Async_SelectPlayerName, &param);

            g_SelectCounter.IncRef();
        }

        {
            CMsgTyped param;
            param.SetInt( i + 1 );
            _PROC->Call(_CONFIG->slaves[i].Proc_Family,   Async_SelectFamilyName,  &param);

            g_SelectCounter.IncRef();
        }
    }

    ///////////////////////////////////////////////////////
    g_SelectCounter.Wait0();
    printf("筛选结束。\n");

    // 开始改名
    printf("对现有数据库重名的部分进行更名.. \n");

    map<string, NameExist*, MapStringComp>::iterator it;

    // 改名
    string oldname;
    string newname;

    for (it = m_playerNames.begin(); it != m_playerNames.end(); it++)
    {
        if (!it->second || it->second->m_index.size() < 2) continue;

        // 排序
        sort( it->second->m_index.begin(), it->second->m_index.end(), cp_int );

        printf("%s:   ", it->first.c_str());
        if (it->second ) it->second->Print();

        oldname = it->first;

        int fix = 1;

        for (int i=1; i < it->second->m_index.size(); i++)
        {
            int idx = it->second->m_index[ i ];
            // 改名为 name + i;

            newname = getfix_name( m_playerNames,  oldname, fix);

            // 生成一个任务
           printf("P改名 %s slave[%d]\n",  newname.c_str(),  idx);

           // 投递改名请求

           // Manage 库
           {
                CMsgTyped param;
               param.SetString( oldname.c_str() );
               param.SetString( newname.c_str() );
               bool ok = _PROC->Call( _CONFIG->slaves[ idx - 1].Proc_Manage,   Async_RenamePlayerNameManage,  &param);
               if (ok) g_UpdateCounter.IncRef();
           }

            // Role 库
           {
                CMsgTyped param;
               param.SetString( oldname.c_str() );
               param.SetString( newname.c_str() );
               bool ok = _PROC->Call( _CONFIG->slaves[ idx - 1].Proc_Role,   Async_RenamePlayerNameRole,  &param);
               if (ok) g_UpdateCounter.IncRef();
           }

            // Family 库
           {
                CMsgTyped param;
               param.SetString( oldname.c_str() );
               param.SetString( newname.c_str() );
               bool ok = _PROC->Call( _CONFIG->slaves[ idx - 1].Proc_Family,   Async_RenamePlayerNameFamily,  &param);
               if (ok) g_UpdateCounter.IncRef();
           }

            // Mas 库
           {
                CMsgTyped param;
               param.SetString( oldname.c_str() );
               param.SetString( newname.c_str() );
               bool ok = _PROC->Call( _CONFIG->slaves[ idx - 1].Proc_Master,   Async_RenamePlayerNameMas,  &param);
               if (ok) g_UpdateCounter.IncRef();
           }

            //Mail 库
           {
                CMsgTyped param;
               param.SetString( oldname.c_str() );
               param.SetString( newname.c_str() );
               bool ok = _PROC->Call( _CONFIG->slaves[ idx - 1].Proc_Mail,   Async_RenamePlayerNameMail,  &param);
               if (ok) g_UpdateCounter.IncRef();
           }
        }
    }

    printf("------------------------------------\n");

    for (it = m_FamilyNames.begin(); it != m_FamilyNames.end(); it++)
    {
        if (!it->second || it->second->m_index.size() < 2) continue;

         // 排序
        sort( it->second->m_index.begin(), it->second->m_index.end(), cp_int );

        printf("%s:   ", it->first.c_str());
        if (it->second ) it->second->Print();

        oldname = it->first;

        int fix = 1;

        for (int i=1; i < it->second->m_index.size(); i++)
        {
            int idx = it->second->m_index[ i ];
            // 改名为 name + i;

            newname = getfix_name( m_FamilyNames,  oldname, fix);

            // 生成一个任务
           printf("F改名 %s slave[%d]\n",  newname.c_str(),  idx);

            // 投递改名请求
           CMsgTyped param;
           param.SetString( oldname.c_str() );
           param.SetString( newname.c_str() );
           bool ok = _PROC->Call( _CONFIG->slaves[ idx - 1].Proc_Family,   Async_RenameFamilyName,  &param);
           if (ok) g_UpdateCounter.IncRef();
        }
    }

    g_UpdateCounter.Wait0();
    printf("更名完成. \n");

    printf("对RoleID进行修复\n");
    int id_add = _CONFIG->master.role_id_max;
    for (size_t i=0;  i < _CONFIG->slaves.size();  i++)
    {
        CMsgTyped m;
        m.SetInt( id_add );
        bool ok = _PROC->Call( _CONFIG->slaves[ i ].Proc_Manage,   Async_ReIDManage,  &m);
       if (ok) g_UpRoleIDCounter.IncRef();

        CMsgTyped m2;
        m2.SetInt( id_add );
        ok = _PROC->Call( _CONFIG->slaves[ i ].Proc_Role,   Async_ReIDRole,  &m2);
       if (ok) g_UpRoleIDCounter.IncRef();

       id_add += _CONFIG->slaves[i].role_id_max;
    }

    g_UpRoleIDCounter.Wait0();
    printf("修复完成. \n");

    // 开始合并数据库
    printf("开始合并数据。。。\n");

    // 一个一个表进行拷贝
    for (size_t i=0;  i < _CONFIG->slaves.size();  i++)
    {
        // Manage
        DoJionTable("GlobalRoles",  _CONFIG->slaves[i].Proc_Manage,  _CONFIG->master.Proc_Manage);

        //  Proc_Role
        DoJionTable("GameRoles",  _CONFIG->slaves[i].Proc_Role,  _CONFIG->master.Proc_Role);

        // Proc_Family
        DoJionTable("FamilyInfo",  _CONFIG->slaves[i].Proc_Family,  _CONFIG->master.Proc_Family);
        DoJionTable("FamilyMember",  _CONFIG->slaves[i].Proc_Family,  _CONFIG->master.Proc_Family);

        // Proc_Master
        DoJionTable("MasterInfo",  _CONFIG->slaves[i].Proc_Master,  _CONFIG->master.Proc_Master);
        DoJionTable("StudentInfo",  _CONFIG->slaves[i].Proc_Master,  _CONFIG->master.Proc_Master);

        // Proc_mail
        DoJionTable("MailTable",  _CONFIG->slaves[i].Proc_Mail,  _CONFIG->master.Proc_Mail);
    }

    PrintCnt(true);
}

void Worker::AddPlayerName( const char* name, int index)
{
    if (!name) return;

    map<string, NameExist*, MapStringComp>::iterator it = m_playerNames.find( name ) ;

    if (it == m_playerNames.end())
    {
        // 未找到， 添加
        NameExist* newNode = new NameExist;
        newNode->m_index.push_back( index );

        m_playerNames.insert( std::make_pair(name, newNode) );
    }
    else
    {
        // 找到了
        NameExist* node = it->second;
        node->m_index.push_back( index );
    }
}

void Worker::AddFamilyName(const char* name ,int index)
{
    map<string, NameExist*, MapStringComp>::iterator it = m_FamilyNames.find( name ) ;

    if (it == m_FamilyNames.end())
    {
        // 未找到， 添加
        NameExist* newNode = new NameExist;
        newNode->m_index.push_back( index );

        m_FamilyNames.insert( std::make_pair(name, newNode) );
    }
    else
    {
        // 找到了
        NameExist* node = it->second;
        node->m_index.push_back( index );
    }
}


